package cn.jzq.kotoba.modules.principle.dip;

/**
 * 依赖倒置原则(Dependence Inversion Principle, DIP)
 * https://blog.csdn.net/king123456man/article/details/81626127
 *
 * 依赖：在程序设计中，如果一个模块a使用或调用了另一个模块b，我们称模块a依赖模块b。
 * 高层模块与低层模块：往往在一个应用程序中，我们有一些低层次的类，这些类实现了一些基本的或初级的操作，我们称之为低层模块；另外有一些高层次的类，这些类封装了某些复杂的逻辑，并且依赖于低层次的类，这些类我们称之为高层模块。
 * 依赖倒置原则的2个重要方针：
 * A. 高层模块不应该依赖于低层模块，二者都应该依赖于抽象
 * B. 抽象不应该依赖于细节，细节应该依赖于抽象
 *
 * 为什么叫做依赖倒置（Dependency Inversion）呢？
 * 面向对象程序设计相对于面向过程（结构化）程序设计而言，依赖关系被倒置了。因为传统的结构化程序设计中，高层模块总是依赖于低层模块
 * @author jzq
 * @date 2019/1/24 16:40
 */
public class DipApp {

    public static void main(String[] args) {
        Driver driver = new Driver();
        driver.drive(new Benz());
        // 使用具体类倒置模块与模块之间耦合度太高, 只要需求一变就需要大面积重构
//        1. 系统很难改变，因为每个改变都会影响其他很多部分。
//        2. 当你对某地方做一修改，系统的看似无关的其他部分都不工作了。
//        3. 系统很难被另外一个应用重用，因为你很难将要重用的部分从系统中分离开来。
//        driver.drive(new Bmw());

        DriverDip driverDip = new DriverDip();
        driverDip.drive(new BenzDip());
        driverDip.drive(new BmwDip());

        DriverConstructor driverConstructor = new DriverConstructor(new BenzDip());
        System.out.println("=========");
        driverConstructor.drive();
        driverConstructor.drive(new BmwDip());
    }
}
